﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Media;
#if !XBOX
using Microsoft.Xna.Framework.Input.Touch;
#endif

namespace Brain
{
    public class SoundSystem : IUpdateable, IDrawable, IBaseComponent
    {
        /// <summary>
        /// If the Sound is enabled on the game
        /// </summary>
        public static bool SoundEnabled = false;

        /// <summary>
        /// If the user is Listening to Music
        /// </summary>
        public static bool ListeningToMusic = false;

        public static bool CanPlay()
        {
            return SoundEnabled && !ListeningToMusic;
        }

        /// <summary>
        /// Engine calls this method on Initialize()
        /// on Touch Devices.
        /// For this System to Work, 
        /// DO NOT play ANYTHING before
        /// the Engine.Initialize
        /// method
        /// </summary>
        public static void StartedGame()
        {
            if (MediaPlayer.State == MediaState.Playing)
            {
                // User is listening to music using Zune.
                // We have to ask him if he wants to 
                // listen to the music on the game
                ListeningToMusic = true;
                SoundEnabled = false;
            }
            else
            {
                ListeningToMusic = false;
                SoundEnabled = true;
            }
        }

        /// <summary>
        /// The Sprite to show when the Sound is enabled
        /// </summary>
        public Sprite SoundSprite;

        /// <summary>
        /// The Sprite to show when the Sound is not enabled
        /// </summary>
        public Sprite NoSoundSprite;

        public bool ShouldDraw { get; set; }
        public bool ShouldUpdate { get; set; }

        /// <summary>
        /// Manages Sound on Touch devices. 
        /// NEEDS GestureType of Type TAP to change
        /// Sound State!
        /// </summary>
        /// <param name="sound"></param>
        /// <param name="noSound"></param>
        public SoundSystem(Sprite sound, Sprite noSound)
        {
            this.SoundSprite = sound;
            this.NoSoundSprite = noSound;

            ShouldDraw = true;
            ShouldUpdate = true;
        }
        /// <summary>
        /// Manages Sound on Touch devices. 
        /// NEEDS GestureType of Type TAP to change
        /// Sound State!
        /// </summary>
        /// <param name="sound"></param>
        /// <param name="noSound"></param>
        public SoundSystem(Sprite sound, Sprite noSound, GameScreen gs)
            : this(sound, noSound)
        {
            gs.AddComponent(this);
        }

        /// <summary>
        /// Manages Sound on Touch devices. 
        /// NEEDS GestureType of Type TAP to change
        /// Sound State!
        /// </summary>
        public SoundSystem(string texture, Vector2 position)
        {
            this.SoundSprite = new Sprite();
            this.SoundSprite.TexturePlace = texture;
            this.SoundSprite.Position = position;

            this.NoSoundSprite = new Sprite();
            this.NoSoundSprite.TexturePlace = texture;
            this.NoSoundSprite.Position = position;

            ShouldDraw = true;
            ShouldUpdate = true;
        }
        /// <summary>
        /// Manages Sound on Touch devices. 
        /// NEEDS GestureType of Type TAP to change
        /// Sound State!
        /// </summary>
        public SoundSystem(string texture, Vector2 position, Vector2 scale)
        {
            this.SoundSprite = new Sprite();
            this.SoundSprite.TexturePlace = texture;
            this.SoundSprite.Position = position;
            this.SoundSprite.UpdateBoundsRectangle();
            this.SoundSprite.BoundsRectangle = RectangleUtil.Scale(this.SoundSprite.BoundsRectangle, scale);

            this.NoSoundSprite = new Sprite();
            this.NoSoundSprite.TexturePlace = texture;
            this.NoSoundSprite.Position = position;
            this.NoSoundSprite.BoundsRectangle = this.SoundSprite.BoundsRectangle;

            ShouldDraw = true;
            ShouldUpdate = true;
        }

        public event SetVoid OnUserEnabledSound;
        public event SetVoid OnUserDisabledSound;

        public void Update()
        {
            if (SoundSprite.ShouldUpdate)
            {
                SoundSprite.Update();
            }
            if (NoSoundSprite.ShouldUpdate)
            {
                NoSoundSprite.Update();
            }

#if !XBOX
            this.NoSoundSprite.Color = Color.White;
            this.SoundSprite.Color = Color.White;

            foreach (GestureSample sample in Engine.Instance.InputManager.Gestures)
            {
                if (sample.GestureType == GestureType.Tap)
                {
                    Vector2 pos = sample.Position;
                    /*
                    if (Engine.Instance.RenderManager2D.CustomResMatrix != null)
                    {
                        pos = Vector2.Transform(pos, Matrix.Invert(Engine.Instance.RenderManager2D.CustomResMatrix.Value));
                    }*/
                    Rectangle t = new Rectangle((int)pos.X, (int)pos.Y, 1, 1);

                    if (this.SoundSprite.BoundsRectangle.Intersects(t))
                    {
                        SoundSystem.SoundEnabled = !SoundSystem.SoundEnabled;

                        if (SoundSystem.SoundEnabled)
                        {
                            if (OnUserEnabledSound != null)
                            {
                                OnUserEnabledSound();
                            }
                        }
                        else
                        {
                            if (OnUserDisabledSound != null)
                            {
                                OnUserDisabledSound();
                            }
                        }
                    }
                }
                else if (sample.GestureType == GestureType.FreeDrag)
                {
                    Vector2 pos = sample.Position;
                    /*
                    if (Engine.Instance.RenderManager2D.CustomResMatrix != null)
                    {
                        pos = Vector2.Transform(pos, Matrix.Invert(Engine.Instance.RenderManager2D.CustomResMatrix.Value));
                    }*/
                    Rectangle t = new Rectangle((int)pos.X, (int)pos.Y, 1, 1);

                    if (this.SoundSprite.BoundsRectangle.Intersects(t))
                    {
                        this.NoSoundSprite.Color = new Color(200, 200, 200);
                        this.SoundSprite.Color = new Color(200, 200, 200);
                    }
                }
            }
#endif

            if (SoundSystem.SoundEnabled)
            {
                SoundSprite.Rendering = SpriteRendering.Rendered;
                NoSoundSprite.Rendering = SpriteRendering.Invisible;
            }
            else
            {
                SoundSprite.Rendering = SpriteRendering.Invisible;
                NoSoundSprite.Rendering = SpriteRendering.Rendered;
            }
        }
        public void Draw()
        {
            if (SoundSprite.ShouldDraw)
            {
                SoundSprite.Draw();
            }
            if (NoSoundSprite.ShouldDraw)
            {
                NoSoundSprite.Draw();
            }
        }

        /// <summary>
        /// Ends the In-Game music, if 
        /// the user is not listening to music
        /// </summary>
        public static void StopMusic()
        {
            if (SoundEnabled &&
                !ListeningToMusic)
            {
                MediaPlayer.Stop();
            }
        }


        public bool ShouldSerialize
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public void SerializeData(SerializationData parentData, string index)
        {
            throw new NotImplementedException();
        }

        public void DeserializeData(SerializationData parentData, string index)
        {
            throw new NotImplementedException();
        }

        public string Name
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }


        public void DeserializedAll()
        {
        }
    }
}
